﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Telerik.Web.UI;
using PepsiCo.Business;
using System.Web.Services;
using System.Text;
using System.Data.Linq;

namespace PepsiCo.UI
{
    public partial class UnitManagement : BasePage
    {
        public Guid treeID
        {
            get
            {
                if (ViewState["TreeID"] == null) return Guid.Empty;
                return new Guid(ViewState["TreeID"].ToString());
            }
            set
            {
                if (value == Guid.Empty) ViewState["TreeID"] = null;
                else ViewState["TreeID"] = value;
            }
        }

        public string CheckAddOrEdit
        {
            get
            {
                return (string)ViewState["CheckAddOrEdit"];
            }
            set
            {
                ViewState["CheckAddOrEdit"] = value;
            }
        }

        protected override void OnInit(EventArgs e)
        {
            base.OnInit(e);
            if (!AllowEditUnit() && !AllowCreateUnit() && !AllowDeleteUnit())
                RedirectToPage(AccessDeniedURL);
            pagingtop.PagingChange += new EventHandler(paging_PagingChange);
        }

        void paging_PagingChange(object sender, EventArgs e)
        {
            pagingtop.PagingChange -= new EventHandler(paging_PagingChange);
            pagingtop.CurrentPage = (sender as UserControl.ucPaging).CurrentPage;
            BindDataForGridStaff(treeID);
            pagingtop.Visible = (sender as UserControl.ucPaging).TotalPage > 1;
            pagingtop.PagingChange += new EventHandler(paging_PagingChange);
        }
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                PageSize = Convert.ToInt32(ddlSortable_length.SelectedValue);
                pagingtop.CurrentPage = 1;
                pagingtop.PageSize = PageSize;
                pagingtop.PageDisplay = 6;
                LoadUnit();
                BindType();
                if (CurUser.UnitID.HasValue)
                {
                    RadTreeNodeEventArgs ex = new RadTreeNodeEventArgs(new RadTreeNode());
                    ex.Node.Value = CurUser.UnitID.ToString();
                    RadTreeView_NodeClick(RadTreeView, ex);
                    CheckedNodeByValue(CurUser.UnitID.Value.ToString());
                }
            }
        }

        private void CheckedNodeByValue(string value)
        {
            RadTreeNode node = RadTreeView.FindNodeByValue(value);
            if (node != null)
                node.Selected = true;
        }

        private void LoadUnit()
        {
            var units = DB.pepsi_Units.OrderBy(p => p.OrderID);
            RadTreeView.DataSource = units;
            RadTreeView.DataFieldID = "ID";
            RadTreeView.DataFieldParentID = "ParentID";
            RadTreeView.DataValueField = "ID";
            RadTreeView.DataTextField = "Name";
            RadTreeView.DataBind();
            RadTreeView.ExpandAllNodes();
            BindDropDownUnit();
        }

        private void BindDropDownUnit()
        {
            ddlParentUnit.Items.Add(new ListItem("--Select Item--", string.Empty));
            foreach (var item in DB.pepsi_Units.Where(p => p.ParentID == null).OrderBy(p=>p.OrderID))
            {
                ddlParentUnit.Items.Add(new ListItem(item.Name, item.ID.ToString()));
                ddlUnit.Items.Add(new ListItem(item.Name, item.ID.ToString()));
                BindDropDownUnit(item.ID, "--");
            }
        }
      
        private void BindDropDownUnit(Guid? unitID, string ident)
        {
            var dataSource = DB.pepsi_Units.Where(p => p.ParentID == unitID).OrderBy(p => p.OrderID);
            foreach (var item in dataSource)
            {
                ddlParentUnit.Items.Add(new ListItem(ident + item.Name, item.ID.ToString()));
                ddlUnit.Items.Add(new ListItem(ident + item.Name, item.ID.ToString()));
                BindDropDownUnit(item.ID, Server.HtmlDecode("&nbsp;&nbsp;&nbsp;") + ident);
            }
        }

        private void BindType()
        {
            drdType.DataSource = DB.pepsi_StaffTypes.OrderBy(p => p.StaffTypeName);
            drdType.DataValueField = "StaffTypeID";
            drdType.DataTextField = "StaffTypeName";
            drdType.DataBind();
        }

        private void SetControls(bool edit)
        {
            CtrEdit.Enabled = edit;
        }

        private void SetControlsEdit(bool edit, string name)
        {
            CtrEdit.Visible = edit;
            btnSave.Text = name;
        }

        private void Clear()
        {
            txtUnitName.Text = string.Empty;
            txtZone.Text = string.Empty;
            ddlParentUnit.SelectedValue = "";
        }

        private void BindDataForGridStaff(Guid unitID)
        {
            int? currentPage = pagingtop.CurrentPage;
            int? pageSize = pagingtop.PageSize;
            int? totalRow = 0;
            rptStaff.DataSource =
                DB.sp_pepsi_StaffGetByUnit_Paging(unitID, currentPage, pageSize, ref totalRow);
            pagingtop.TotalRecord = totalRow.Value;
            pagingtop.Visible = pagingtop.TotalPage > 1;
            rptStaff.DataBind();
            ltrInfo.Text = "Total pages: " + pagingtop.TotalPage; 
        }
        
        protected void RadTreeView_ContextItemClick(object sender, Telerik.Web.UI.RadTreeViewContextMenuEventArgs e)
        {
            switch (e.MenuItem.Value)
            {
                case "Add":
                    if (!AllowCreateUnit())
                        return;
                    CheckAddOrEdit = "Add";
                    txtUnitName.Focus();
                    SetControlsEdit(true, "Save");
                    Clear();
                    treeID = Guid.NewGuid();
                    hdfTreeID.Value = treeID.ToString();
                    rptStaff.DataSource = null;
                    rptStaff.DataBind();
                    break;
                case "Delete":
                    if (!AllowDeleteUnit())
                        return;
                    treeID = new Guid(e.Node.Value);
                    hdfTreeID.Value = e.Node.Value;
                    pepsi_Unit deleteObj = DB.pepsi_Units.FirstOrDefault(p => p.ID == treeID);
                    if (deleteObj != null)
                    {
                        DB.pepsi_Units.DeleteOnSubmit(deleteObj);
                        DB.SubmitChanges();
                    }
                    Response.Redirect(Request.RawUrl);
                    break;
                default:
                    break;
            }
        }

        protected void RadTreeView_NodeClick(object sender, RadTreeNodeEventArgs e)
        {
            if (treeID != new Guid(e.Node.Value))
            {
                CheckAddOrEdit = "Edit";
                txtUnitName.Focus();
                treeID = new Guid(e.Node.Value);
                hdfTreeID.Value = e.Node.Value;
                SetControlsEdit(true, "Update");
                pepsi_Unit objUnit = DB.pepsi_Units.FirstOrDefault(p => p.ID == treeID);
                if (objUnit != null)
                {
                    txtUnitName.Text = objUnit.Name;
                    ddlParentUnit.SelectedValue = objUnit.ParentID.HasValue ? objUnit.ParentID.ToString() : "";
                    txtZone.Text = objUnit.Zone;
                    txtOrder.Text = objUnit.OrderID.HasValue ? objUnit.OrderID.ToString() : "0";
                    SetControls(true);
                    BindDataForGridStaff(objUnit.ID);
                }
            }
        }

        protected void btnCancel_Click(object sender, EventArgs e)
        {
            Clear();
        }
        
        protected void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                pepsi_Unit objUnit = new pepsi_Unit();
                Guid? parentID = ddlParentUnit.SelectedValue == "" ? (Guid?)null : new Guid(ddlParentUnit.SelectedValue);
                switch (CheckAddOrEdit)
                {
                    case "Add":
                        if (!AllowCreateUnit())
                        {
                            throw new Exception("You don't have permission create Unit");
                        }
                        if (!IsAdmin())
                        {
                            if (!CheckPrivileges(CurUser.UnitID, parentID))
                            {
                                throw new Exception("You don't have permission create a Unit have level greater than your Unit level");
                            }
                        }
                        objUnit.ID = treeID;
                        DB.pepsi_Units.InsertOnSubmit(objUnit);
                        break;
                    case "Edit":
                        if (!AllowEditUnit())
                        {
                            throw new Exception("You don't have permission edit Unit");
                        }
                        objUnit = DB.pepsi_Units.FirstOrDefault(p => p.ID == treeID);
                        if (!IsAdmin())
                        {
                            if (!CheckPrivileges(CurUser.UnitID, objUnit.ID))
                            {
                                throw new Exception("You don't have permission edit this Unit");
                            }
                            if (!CheckPrivileges(CurUser.UnitID, parentID))
                            {
                                throw new Exception("You don't have permission edit a Unit have level greater than your Unit level");
                            }
                        }
                        break;
                }
                objUnit.Name = txtUnitName.Text;
                objUnit.Zone = txtZone.Text;
                objUnit.OrderID = string.IsNullOrEmpty(txtOrder.Text.Trim()) ? 0 : int.Parse(txtOrder.Text.Trim());
                objUnit.ParentID = parentID;
                DB.SubmitChanges();
                RedirectToPage(Request.RawUrl);
            }
            catch (Exception ex)
            {
                ScriptManager.RegisterStartupScript(this, this.GetType(), "", "alert(\"" + ex.Message + "\");", true);
            }
        }

        protected void btnClose_Click(object sender, EventArgs e)
        {
            CtrEdit.Visible = false;
        }

        private void SetNullDataSource()
        {
            rptStaff.DataSource = null;
            rptStaff.DataBind();
        }

        private bool CheckPrivileges(Guid? unit1ID, Guid? unit2ID)
        {
            if (IsAdmin())
                return true;
            if (DB.fn_CompareUnitLevel(unit1ID, unit2ID) > 0)
                return false;
            return true;
        }


        protected void ddlSortable_length_SelectedIndexChanged(object sender, EventArgs e)
        {
            PageSize = Convert.ToInt32(ddlSortable_length.SelectedValue);
            pagingtop.PageSize = PageSize;
            BindDataForGridStaff(treeID);
        }

        #region WebServices
        public static PepsiCoDBDataContext db = new PepsiCoDBDataContext(LocalSetting.ConnectionString);

        [WebMethod]
        public static object StaffGetById(Guid staffId, Guid unitId)
        {
            return db.pepsi_Staffs
                .Where(p => p.StaffID == staffId)
                .Select(p=>new{
                        p.StaffID,
                        p.StaffCode,
                        p.StaffName,
                        p.Gender,
                        p.Address,
                        p.UnitID,
                        p.StaffLevel,
                        p.Actived,
                        p.StaffTypeID,
                        UnitName = p.pepsi_Unit.Name,
                        PhoneNumber = db.fn_getStaffPhoneList(staffId)
                    })
                .FirstOrDefault();
        }

        [WebMethod]
        public static object StaffGetByUnitId(Guid unitId, int curentPage, int pageSize)
        {
            int? totalRecord = 0;
            return db.sp_pepsi_StaffGetByUnit_Paging(unitId, curentPage, pageSize, ref totalRecord)
                .Select(p => new
                {
                    p.StaffID,
                    p.StaffCode,
                    p.StaffName,
                    p.Gender,
                    p.Address,
                    p.Actived,
                    p.UnitID,
                    p.UnitName,
                    p.StaffType,
                    p.StaffLevel
                });
        }

        [WebMethod]
        public static bool StaffUpdate(Guid staffId, Guid unitId, string staffcode, string staffname, bool gender, string address, int stafflevel, short stafftype, bool actived, string phonenumber)
        {
            try
            {
                pepsi_Staff staff = db.pepsi_Staffs.FirstOrDefault(p => p.StaffID == staffId);
                if (staff != null)
                {
                    //Update staff
                    staff.StaffCode = staffcode;
                    staff.StaffName = staffname;
                    staff.Gender = gender;
                    staff.Address = address;
                    staff.Actived = actived;
                    staff.UnitID = unitId;
                    staff.StaffLevel = stafflevel;
                    staff.StaffTypeID = stafftype;
                    db.SubmitChanges();
                    //Update contact
                    var contacts = db.pepsi_Contacts.Where(p => p.StaffID == staffId);
                    if (contacts != null)//delete old contact
                        db.pepsi_Contacts.DeleteAllOnSubmit(contacts);
                    short i = 0;
                    foreach (string item in phonenumber.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries)) //Re add contact
                    {
                        pepsi_Contact contact = new pepsi_Contact();
                        contact.StaffID = staffId;
                        contact.PhoneNumber = item.ToNormalPhoneNumber();
                        if (!contact.ValidatePhoneNumber(contact.PhoneNumber))
                        {
                            throw new Exception("Phone number is invalid!");
                        }
                        contact.OperatorID = contact.GetOperatorID();
                        contact.Actived = true;
                        contact.Priority = (++i);
                        db.pepsi_Contacts.InsertOnSubmit(contact);
                    }
                    //Update User (Khi cập nhật lại Unit cho Staff thì Unit của User của staff đó phải được cập nhật theo)
                    var user = db.pepsi_Users.FirstOrDefault(p => p.StaffID == staff.StaffID);
                    if (user != null)
                    {
                        user.UnitID = unitId;
                        //user.pepsi_Unit.ID = unitId;
                    }
                    db.SubmitChanges(ConflictMode.ContinueOnConflict);
                    //db.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, db.pepsi_Staffs);
                    return true;
                }
            }
            catch (Exception ex)
            {
                throw ex;
            }
            return false;
        }

        [WebMethod]
        public static void StaffInsert(string staffcode, string staffname, bool gender, string address, string phonenumber, int stafflevel, short stafftype, bool actived, Guid unitId)
        {
            //Add new staff
            pepsi_Staff newStaff = new pepsi_Staff();
            newStaff.StaffID = Guid.NewGuid();
            newStaff.StaffCode = staffcode;
            newStaff.StaffName = staffname;
            newStaff.Gender = gender;
            newStaff.Address = address;
            newStaff.UnitID = unitId;
            newStaff.StaffID = newStaff.StaffID;
            newStaff.StaffLevel = stafflevel;
            newStaff.StaffTypeID = stafftype;
            newStaff.Actived = true;
            db.pepsi_Staffs.InsertOnSubmit(newStaff);
            //Add Contacts
            string[] phonelist = phonenumber.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
            short i = 0;
            foreach (string item in phonelist)
            {
                pepsi_Contact newContact = new pepsi_Contact();
                newContact.StaffID = newStaff.StaffID;
                newContact.PhoneNumber = item.ToNormalPhoneNumber();
                newContact.OperatorID = newContact.GetOperatorID();
                newContact.Actived = true;
                newContact.Priority = (++i);
                db.pepsi_Contacts.InsertOnSubmit(newContact);
            }
            //Commit Change to database
            db.SubmitChanges();
        }

        [WebMethod]
        public static void StaffDeleteById(Guid staffId, Guid unitId)
        {
            var staff = db.pepsi_Staffs.FirstOrDefault(p => p.StaffID == staffId);
            if (staff != null)
            {
                //Delete contact
                var contacts = db.pepsi_Contacts.Where(p => p.StaffID == staffId);
                if (contacts != null)
                    db.pepsi_Contacts.DeleteAllOnSubmit(contacts);
                db.pepsi_Staffs.DeleteOnSubmit(staff);
                db.SubmitChanges();
            }
        }

        [WebMethod]
        public static void StaffDeleteByListOfId(string listOfId, Guid unitId)
        {
            //var deleteOjb = db.pepsi_Staffs.Where(p => listOfId.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Contains(p.StaffID.ToString()));
            //if (deleteOjb != null)
            //{
            //    foreach (var item in deleteOjb)
            //    {
            //        //Delete contact
            //        var contacts = db.pepsi_Contacts.Where(p => p.StaffID == item.StaffID);
            //        if (contacts != null)
            //            db.pepsi_Contacts.DeleteAllOnSubmit(contacts);
            //        //Delete 
            //    }
            //}
        }

        [WebMethod]
        public static bool CheckExistsStaffCode(Guid? staffId, string staffcode)
        {
            return pepsi_Staff.CheckExistsStaffCode(staffId, staffcode);
        }

        [WebMethod]
        public static bool CheckValidPhoneNumber(string phonelist)
        {
            return pepsi_Contact.CheckValidPhoneNumber(phonelist.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
        }

        [WebMethod]
        public static bool CheckExistsPhoneNumber(Guid staffId, string phonelist)
        {
            return pepsi_Contact.CheckExistsPhoneNumber(staffId, phonelist.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
        }

        [WebMethod]
        public static bool checkPrivileges(Guid? unit1ID, Guid? unit2ID)
        {
            pepsi_User cur_user= HttpContext.Current.Session[_SESSION.USER_NAME] as pepsi_User;
            if (cur_user == null) return false;
            if (cur_user.IsAdmin())
                return true;
            if (db.fn_CompareUnitLevel(unit1ID, unit2ID) > 0)
                return false;
            return true;
        }

        #endregion

    }
}